/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.service.javabeans;

import opiam.admin.faare.config.javabeans.JBRessource;
import opiam.admin.faare.exception.ConfigurationException;
import opiam.admin.faare.exception.PersistenceException;
import opiam.admin.faare.persistence.LdapObjectFilter;
import opiam.admin.faare.service.UserContext;

import org.apache.log4j.Logger;


/**
 * This class allows to define a search argument.<br>
 * This argument is built from :
 *  <li>requested object type : opiam.admin.faare.config.javabeans.JBRessource type object</li>
 *  <li>criteria : opiam.admin.faare.service.javabeans.Criteria type object.</li>
 */
public class SearchArgument
{
    /** Instance of logger. */
    private static Logger _logger = Logger.getLogger(SearchArgument.class);

    /** Criteria. */
    private Criteria criteria;

    /** Resource. */
    private JBRessource jbRessource;

    /** Context of user. */
    private UserContext userContext;

    /**
     * Creates a new SearchArgument object.
     * Throws ConfigurationException (RuntimeException) in case of null argument.
     *
     * @param acriteria  Search criterion.
     * @param ajbRessource  A resource such as defined in the profiles configuration file.
     * @param auserContext  Context of the user.
     *
     */
    public SearchArgument(Criteria acriteria, JBRessource ajbRessource,
        UserContext auserContext)
    {
        if (acriteria == null)
        {
            throw new ConfigurationException("SearchArgument criteria null");
        }

        if (ajbRessource == null)
        {
            throw new ConfigurationException("SearchArgument jbRessource null");
        }

        this.criteria = acriteria;
        this.jbRessource = ajbRessource;
        this.userContext = auserContext;
    }

    /**
     * Creates a new SearchArgument object.
     * Throws ConfigurationException (RuntimeException) in case of null argument.
     *
     * @param ajbRessource  A resource such as defined in the profiles configuration file.
     * @param auserContext  User context.
     */
    public SearchArgument(JBRessource ajbRessource, UserContext auserContext)
    {
        if (ajbRessource == null)
        {
            throw new ConfigurationException("SearchArgument jbRessource null");
        }

        this.jbRessource = ajbRessource;
        this.userContext = auserContext;
    }

    /**
     * Returns the criteria.
     *
     * @return The criteria object.
     */
    public Criteria getCriteria()
    {
        return criteria;
    }

    /**
     * Returns the jbRessource.
     *
     * @return The JBRessource object.
     */
    public JBRessource getJbRessource()
    {
        return jbRessource;
    }

    /**
     * Returns the ldap filter.
     *
     * @return A String representing the ldap filter.
     *
     * @throws Exception in case the filter contains
     *         attributes undefined for the corresponding resource.
     */
    public String getLdapFilter() throws Exception
    {
        _logger.debug("getLdapFilter");

        StringBuffer filter = new StringBuffer();
        filter.append("(&");

        try
        {
            filter.append(LdapObjectFilter.getLdapFilterFromResource(
                    jbRessource, userContext));

            if (jbRessource.getObjectFilterParam() != null)
            {
                _logger.debug(
                    "getLdapFilter jbRessource.getObjectFilterParam() != null");

                filter.append(LdapObjectFilter.convertObjectToLdapFilter(
                        jbRessource, userContext));
            }

            if (criteria != null)
            {
                String filterCriteria = criteria.getLdapFilter(jbRessource,
                        userContext);

                _logger.debug(
                    "getLdapFilter jbRessource.getClassDesc().getName() : " +
                    jbRessource.getClassDesc().getName());

                _logger.debug(
                    "getLdapFilter jbRessource.getClassDesc().getField2AttrConversion() : " +
                    jbRessource.getClassDesc().getField2AttrConversion());

                _logger.debug("getLdapFilter filterCriteria : " +
                    filterCriteria);

                filter.append(filterCriteria);
            }
        }
        catch (PersistenceException e)
        {
            return "";
        }

        filter.append(")");

        return filter.toString();
    }

    /**
     * Returns the basic dn.
     *
     * @return A String representing the basic dn.
     */
    public String getLdapBase()
    {
        String base = jbRessource.getLdapBaseParam();

        if (base == null)
        {
            base = userContext.getLdapConfig().getBaseDN();
        }

        return base;
    }

    /**
     * Returns the set of the search attributes.
     *
     * @return A array of the attributes names.
     */
    public String[] getLdapSearchAttributes()
    {
        return jbRessource.getClassDesc().getLdapAttributes();
    }

    /**
     * Returns the scope of search.
     *
     * @return An int representing the scope.
     */
    public int getLdapScope()
    {
        return jbRessource.getLdapScopeParam();
    }
}
